/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package smsserver.manager;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import smscommon.Global;
import smsserver.SmsServerView;
import smsserver.utils.User;

/**
 *
 * @author ZHENG ZHI YOU
 */
public class SmsServerManager {
    private static SmsServerManager ssm = null;

    private static IoAcceptor acceptor = null;
    private static Map<IoSession, User> clientMap = Collections.synchronizedMap(new HashMap<IoSession, User>());


    private static SmsServerView ssv = null;

    public static SmsServerManager getInstance()
    {
        if(ssm==null)
        {
            ssm = new SmsServerManager();
        }
        return ssm;
    }

    public boolean serverStart()
    {
         //绑定IP,启动服务
        if(serIsActive())
        {
            ssv.showMessage("服务器已经启动");
            return true;
        }
        try {
            acceptor = Global.CreateIoAcceptor();
            if(acceptor!=null)
            {
                acceptor.getFilterChain().addLast("logger", new LoggingFilter());
                acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory( Charset.forName( "UTF-8" ) )));
                acceptor.setHandler(new ClientHandler());
                //Buffer大小告诉底层操作系统应该分配多大空间放置到来的数据；第二行指明什么时候应该检测session空闲。在setIdleTime方法中，第一参数定义当session空闲时，检测那些活动，第二个参数定义session变为空闲状态时需要经过多长的时间。
                acceptor.getSessionConfig().setReadBufferSize(Global.BUFF_SIZE);
                acceptor.getSessionConfig().setWriteTimeout(Global.W_TIME_OUT);
                //检测SESSION,读写通道10秒内没有反映进入空闲通道
                acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, Global.BOTH_IDLE_TIME);
                acceptor.bind(new InetSocketAddress(Global.PORT));
                ssv.showMessage("服务器启动成功");
            }else{
                ssv.showMessage("服务器启动失败1");
            } 
        } catch (IOException ex) {
            Logger.getLogger(SmsServerManager.class.getName()).log(Level.SEVERE, null, ex);
            ssv.showMessage("服务器启动失败");
            return false;
        }
        return true;
    }

    public void setView(SmsServerView view)
    {
        ssv = view;
    }

    public boolean serIsActive()
    {
        if(acceptor!=null)
        {
            return acceptor.isActive();
        }
        return false;
    }

    public void serverStop()
    {
        if(acceptor!=null)
        {
            acceptor.unbind();;
            acceptor.setCloseOnDeactivation(true);
            acceptor = null;
            ssv.moveAllUser();
            ssv.showMessage("服务器关闭成功");  
        }
    }





    public void addclient(IoSession session,User user)
    {
        if(clientMap.containsKey(session))
        {
            delclient(session);
        }
        clientMap.put(session, user);
        ssv.addUser(user);
    }


    public void delclient(IoSession session)
    {
        ssv.delUser(getUser(session));
        clientMap.remove(session);
        session.close(true);
    }

    public User getUser(IoSession session)
    {
        if(clientMap.containsKey(session))
        {
            return clientMap.get(session);
        }
        return null;
    }

    public User getUser(String iccid)
    {
        IoSession session = getSession(iccid);
        if(clientMap.containsKey(session))
        {
            return clientMap.get(session);
        }
        return null;
    }


    public void showMessage(String message)
    {
        ssv.showMessage(message);
    }


    public IoSession getSession(String iccid)
    {
        IoSession session = null;
        for(IoSession sess:clientMap.keySet())
        {
            if(clientMap.get(sess).getIccid().equals(iccid))
            {
                return clientMap.get(sess).getSession();
            }
        }
        return session;
    }

    public void broadcastClient(int indexed,String message)
    {
        switch(indexed)
        {
            case 0:
            case 1:
            case 2:
                broadcastUser(indexed,message);
                break;
            case 3:
                acceptor.broadcast(message);
                break;
        }
    }

    public void broadcastUser(int indexed,String message)
    {
        for(IoSession user:clientMap.keySet())
        {
            if(clientMap.get(user).getIndex()==indexed)
            {
                IoSession session = clientMap.get(user).getSession();
                WriteFuture wf = session.write(message);
                if(wf.isWritten())
                {
                    System.out.println(clientMap.get(user).getIccid()+"发送："+message+"  \n发送成功");
                }
            }
        }
    }
}
